﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Configuration;
using SdmxMl.Common;


namespace SmsMeta
{
    public class RessourceQuery: IRestRequest
    {
        private bool foundRessource;
        public bool IsImplemented { get; set; }
        public ArtefactRefTyped ArTyped { get; set; }

        public RessourceDomain Domain { get; set; }
        StructuralMetaQueries Structural { get; set; }
        DataAndMetadataQueries DataAndMeta { get; set; }
        SchemaQueries Schema { get; set; }

        public RessourceQuery(HttpRequest r)
            : base(r) 
        {
            foundRessource = false;
            IsImplemented = false;

            ArTyped = new ArtefactRefTyped(SdmxMl.Manager.SdmxArtefactType.None, string.Empty, string.Empty, string.Empty);

            if (this.Verb == RestVerbs.GET && this.Arguments.Length > 0)
            {
                 foreach (StructuralMetaQueries otc in Enum.GetValues(typeof(StructuralMetaQueries)))
                     if (otc.ToString() == this.Arguments[0])
                     {
                         foundRessource = true;
                         Domain = RessourceDomain.StructuralMetadata;
                         Structural = otc;
                         break;
                     }

                 if (!foundRessource)
                 {
                     foreach (DataAndMetadataQueries otc in Enum.GetValues(typeof(DataAndMetadataQueries)))
                         if (otc.ToString() == this.Arguments[0])
                         {
                             foundRessource = true;
                             Domain = RessourceDomain.DataAndMetaData;
                             DataAndMeta = otc;
                             break;
                         }
                 }

                 if (!foundRessource)
                 {
                     foreach (SchemaQueries otc in Enum.GetValues(typeof(SchemaQueries)))
                         if (otc.ToString() == this.Arguments[0])
                         {
                             foundRessource = true;
                             Domain = RessourceDomain.Schema;
                             Schema = otc;
                             break;
                         }
                 }

                 if (foundRessource)
                 {
                     // Determines parameters validity
                     if (Domain == RessourceDomain.StructuralMetadata)
                     {
                         UpdateArtefactType();
                         IsImplemented = ArTyped.Type != SdmxMl.Manager.SdmxArtefactType.None;
                     }
                 }

           }
        }

        public override Boolean IsValid
        {
            get
            {
                if (this.Verb != RestVerbs.GET)
                {
                    this.StatusCode = (Int32)HttpStatus.MethodNotAllowed;
                    return false;
                }

                string restDir = ConfigurationSettings.AppSettings["RestDir"].Trim().ToUpper();
                if (this.Arguments.Length < 1 || this.Method.ToUpper() != restDir)
                {
                    this.StatusCode = (Int32)HttpStatus.BadRequest;
                    return false;
                }

                // Invalid request


                // Not supported request
                if (IsImplemented == false)
                {
                    this.StatusCode = (Int32)HttpStatus.NotImplemented;
                    return false;
                }



                return true;
            }
        }

        public void UpdateArtefactType()
        {
            // Default for missing arguments
                ArTyped.AgencyId = "all";
                ArTyped.Id = "all";
                ArTyped.Version = "latest";

                if (this.Arguments.Length > 1)
                    ArTyped.AgencyId = this.Arguments[1];
                if (this.Arguments.Length > 2)
                    ArTyped.Id = this.Arguments[2];
                if (this.Arguments.Length > 3)
                    ArTyped.Version = this.Arguments[3];

                if (Domain == RessourceDomain.StructuralMetadata)
                {
                    switch (this.Structural)
                    {
                        case StructuralMetaQueries.codelist:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.CodeLists; break;
                        case StructuralMetaQueries.hierarchicalcodelist:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.HierarchicalCodelists; break;
                        case StructuralMetaQueries.organisationscheme:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.OrganisationSchemes; break;
                        case StructuralMetaQueries.conceptscheme:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.Concepts; break;

                        case StructuralMetaQueries.categoryscheme:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.CategorySchemes; break;
                        case StructuralMetaQueries.datastructure:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.KeyFamilies; break;
                        case StructuralMetaQueries.metadatastructure:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.MetadataStructureDefinitions; break;
                        case StructuralMetaQueries.metadataflow:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.Metadataflows; break;
                        case StructuralMetaQueries.dataflow:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.Dataflows; break;
                        case StructuralMetaQueries.process:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.Processes; break;
                        case StructuralMetaQueries.metadataset:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.MetadataSet; break;
                        case StructuralMetaQueries.structureset:
                            ArTyped.Type = SdmxMl.Manager.SdmxArtefactType.StructureSets; break;

                    }                    
                }
        }


    }


}
